package com.ruoyi.sso.service.impl;


import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.exception.base.BaseException;
import com.ruoyi.sso.domain.CommonUser;
import com.ruoyi.sso.domain.SsoLoginBody;
import com.ruoyi.sso.domain.SsoUser;
import com.ruoyi.sso.other.constant.SsoConstant;
import com.ruoyi.sso.service.CodeManager;
import com.ruoyi.sso.service.ICommonApplicationService;
import com.ruoyi.sso.service.ICommonUserService;
import com.ruoyi.sso.service.ILoginService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import static com.ruoyi.sso.other.constant.Oauth2Constant.AUTH_CODE;


/**
 * @author weimingzhong
 * @date 2022/10/26 15:03
 * @remark
 */
@Service
public class LoginServerImpl implements ILoginService {

    private static final Logger log = LoggerFactory.getLogger(LoginServerImpl.class);

    @Autowired
    private ICommonUserService commonUserService;

    @Autowired
    private ICommonApplicationService commonApplicationService;

    @Autowired
    private SessionManager sessionManager;

    @Autowired
    private CodeManager codeManager;


    @Override
    public Map<String, Object> loginCheck(String redirectUri, String appId, HttpServletRequest request) {

        if (!commonApplicationService.checkRedirectUriAndAppId(redirectUri, appId)) {
            throw new BaseException("回调地址或appId错误");
        }
        String tgt = sessionManager.getTgt(request);
        //如果统一登录网页cookie没有tgt，就前端输入账号密码进行统一登录，已经登录拥有tgt,返回一次性使用票据st
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isEmpty(tgt)) {
            // 生成一次性使用的授权码
            map.put(SsoConstant.STATUS_CODE, HttpStatus.ACCEPTED);
            return map;
        } else {
            // 生成一次性使用的授权码
            String code = codeManager.generate(tgt, true, redirectUri);
            map.put(SsoConstant.STATUS_CODE, HttpStatus.SUCCESS);
            map.put(AUTH_CODE, code);
            return map;
        }
    }

    @Override
    public String login(SsoLoginBody loginBody, HttpServletRequest request, HttpServletResponse response) {
        if (!commonApplicationService.checkRedirectUriAndAppId(loginBody.getRedirectUri(), loginBody.getAppId())) {
            throw new BaseException("回调地址或appId错误");
        }
        CommonUser commonUser = commonUserService.selectCommonUserByUserName(loginBody.getUsername());
//        if (ObjectUtils.isEmpty(commonUser) || !SecurityUtils.matchesPassword(loginBody.getPassword(), commonUser.getPassword())) {
//            throw new BaseException("用户不存在或者密码错误");
//        }
        //票据
        String tgt = sessionManager.setUser(new SsoUser(commonUser.getUserId(), commonUser.getUserName()), request, response);
        // 生成授权码
        String code = codeManager.generate(tgt, true, loginBody.getRedirectUri());
        //返回url
        return addCodeToRedirectUri(loginBody.getRedirectUri(), code);
    }


    /**
     * 将只允许使用一次的code拼接到回调redirectUri中
     *
     * @param redirectUri 回调网址
     * @param param       参数
     * @return URL
     */
    private String addCodeToRedirectUri(String redirectUri, String param) {
        StringBuilder sbf = new StringBuilder(redirectUri);
        if (redirectUri.contains("?")) {
            sbf.append("&");
        } else {
            sbf.append("?");
        }
        sbf.append(AUTH_CODE).append("=").append(param);
        try {
            return URLDecoder.decode(sbf.toString(), "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
}
